package algebra.visitors.cursors;

import java.util.ArrayList;
import java.util.List;
import algebra.op.*;
import entities.assertion.ConceptAssertion;
import entities.concept.AndConcept;
import entities.concept.Concept;

public abstract class CACursor {

	// simulates OPEN
	public abstract boolean openCursor();

	public abstract ConceptAssertion getNextResult();
	
	//this method considers if the results returned by a cursor is sorted by the object idenitifier
	public abstract boolean isSortedById();

	public static CACursor getNewCACursor(AlgebraicOP op) {
		CACursor cur = null;
		if (op instanceof PrimaryOP) {
			return new CACursorPI(op.asPrimaryOP());
		} else if (op instanceof ProjectionOP) {
			return new CACursorProjection(op.asProjectionOP());
		} else if (op instanceof SelectionOP) {
			return new CACursorSelection(op.asSelectionOP());
		} else if (op instanceof ConstantOP) {
			return new CACursorConstant(op.asConstantOP());
		} else if (op instanceof JoinOP) {
			return new CACursorJoin(op.asIntersectionOP());
		} else if (op instanceof ScanOP) {
			return new CACursorScan(op.asScanOP());
		} else {
			System.err.println("Unknown cursor type requested for OP: " + op);
		}
		return cur;
	}

	public static List<ConceptAssertion> getResultSet(AlgebraicOP op) {
		List<ConceptAssertion> ret = new ArrayList<ConceptAssertion>();
		CACursor cur = getNewCACursor(op);
		cur.openCursor();
		ConceptAssertion ca = cur.getNextResult();
		while (ca != null) {
			ret.add(ca);
			ca = cur.getNextResult();
		}
		return ret;
	}

	public static String renderCA(ConceptAssertion ca) {
		String ret = "\n";
		ret += ca.getIndividual().toString() + ": \n";
		Concept c = ca.getConcept();
		if (c instanceof AndConcept) {
			AndConcept and = (AndConcept) c;
			for (Concept cc : and.getConceptSet()) {
				if (cc instanceof AndConcept) {
					for (Concept dd : ((AndConcept) cc).getConceptSet()) {
						ret += dd.toString() + "\n";
					}
				} else
					ret += cc.toString() + " \n";
			}
			ret = ret.substring(0, ret.length() - 1);
		} else {
			ret += c.toString();
		}
		return ret;
	}

}
